 #ifndef MESSAGESOCKET_H
#define MESSAGESOCKET_H

#include <QObject>
#include <QUdpSocket>
#include <QMap>
#include <QHostAddress>
#include <QPixmap>
#include <QVector>
#include <QPair>
#include <QByteArray>

class MessageSocket : public QObject
{

    typedef QMap<QString, QHostAddress>::iterator HostAddressMapIterator;
    //Udp传输聊天信息这是报头信息，用来确认消息类型
    enum MessageType{
        MessageTypeLogin = 0, MessageTypeExit, MessageTypeEchoLogin,
        MessageTypeName, MessageTypePhoto, MessageTypeImage, MessageTypeText,
    };
    typedef quint16 UdpMessageType;
    struct UdpHead{
        char m_uuid[32];
        UdpMessageType m_type;
        quint16 m_messageLength;
    };

    Q_OBJECT
public:
    explicit MessageSocket(const QString &uuid, QObject *parent = 0,
                           quint16 broadcastPort = 53737,
                           quint16 udpPort = 35753
                           );
    //获取对应uuid的网络地址
    QHostAddress getHostAddress(const QString &uuid);
    //广播发送
    bool sendLoginMessage(const QString &yourName);
    bool sendNameMessage(const QString &yourName);
    bool sendPhotoMessage(const QPixmap &photo);
    bool sendExitMessage();
    //单播UDP发送
    bool sendText(const QString &friendUuid, const QString &message);
    bool sendEchoLoginMessage(const QString &friendUuid, const QString &name);
    bool sendPhotoMessage(const QString &uuid, const QPixmap &photo);
    bool sendImageMessage(const QString &uuid, const QPixmap &image);

signals:
    void hasLoginMessage(const QString &friendUuid, const QString &friendName);
    void hasNameMessage(const QString &friendUuid, const QString &friendName);
    void hasPhotoMessage(const QString &friendUuid, const QPixmap &friendPhoto);
    void hasImageMessage(const QString &friendUuid, const QImage &image);
    void hasExitMessage(const QString &friendUuid);
    void hasTextMessage(const QString &friendUuid, const QString &text);
    void hasEchoLoginMessage(const QString &friendUuid, const QString &friendName);

public slots:
    void onSocketBroadcastReadyRead();
    void onSocketUdpReadyRead();

private:
    //发送图片
    bool sendImage(QUdpSocket *socket, QHostAddress addr, quint16 port,
                   const QPixmap &pixMap, MessageSocket::MessageType messageType);
    //判断是否是本地IP
    bool IsLocalhostIp(const QString &ip);
    //向准备发送数据报中添加指定报头
    void setUdpHead(QByteArray &array, MessageType type, int messageSize);
    //从UdpHead中获取QString类型的Uuid
    QString getUuid(const MessageSocket::UdpHead *head);
    //接受图片消息，接收完成返回已经接收成功的图片信息在saveVector的下标，没有-1
    int recvImage(const QString &uuid, const QByteArray &message,
                  QVector<QPair<QString, QByteArray> > &saveVector);

private:
    quint16     m_portBroadcast;
    quint16     m_portUdp;
    QUdpSocket *m_socketBroadcast;
    QUdpSocket *m_socketUdp;

    QString     m_uuid;
    QByteArray  m_byteArrayUuid;
    int         m_udpHeadSize;
    //存储uuid与网络地址的映射，查找地址方便
    QMap<QString, QHostAddress> m_hostAddressMap;

    //用于存储好友发过来的头像图片，因为udp不能一次接收完所有集中存储
    QVector<QPair<QString, QByteArray> > m_friendPhotos;
    //用于存储好友发过来的图片
    QVector<QPair<QString, QByteArray> > m_friendImages;
};

#endif // MESSAGESOCKET_H
